package com.SmartCare.aspect;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.SmartCare.common.enums.Constants;
import com.SmartCare.common.exception.ServiceException;
import com.SmartCare.common.note.Monitor;
import com.SmartCare.pojo.apiLog.ApiLog;
import com.SmartCare.service.apiLog.ApiLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.time.LocalDate;

/**
 * 捕获自定义注解 @Monitor并记录调用次数
 */

@Aspect
@Component
public class MonitorAspect {

    @Resource
    ApiLogService apiLogService;

    // 通过切面，配合session的信息完成日志记录
    @Before("@annotation(monitorAnnotation)")
    public void countMethodCalls(JoinPoint joinPoint, Monitor monitorAnnotation) {
        // 获取HttpServletRequest对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        try {
            Integer role = (Integer) attributes.getRequest().getSession().getAttribute("role");
            // 请求身份为家属
            if (attributes != null && role != null) {
                if (role == -1) {
                    // 获取被调用接口的名称
                    String apiName = joinPoint.getSignature().toShortString();
                    // 去除名称中后四位的括号和省略号
                    apiName = apiName.substring(0, apiName.length() - 4);

                    // 获取 @Monitor 注解中的属性
                    String description = monitorAnnotation.description();
                    String module = monitorAnnotation.module();

                    HttpSession session = attributes.getRequest().getSession();
                    long userId ;
                    String chName;
                    try {
                        // 从session中获取需要的信息
                        userId = (Long) session.getAttribute("userId");
                        chName = (String) session.getAttribute("chName");

                    } catch (Exception e) {
                        // 捕捉异常并返回 400 错误
                        throw new ServiceException("400", "未传递session的JSESSIONID值");
                    }
                    // 查询数据库中今日是否存在该接口的记录
                    ApiLog one = apiLogService.getOne(
                            new QueryWrapper<ApiLog>()
                                    .eq("api_name", apiName)
                                    .eq("create_date", LocalDate.now())
                                    .eq("user_id", userId)
                                    .eq("ch_name", chName)
                    );

                    if (one == null) {
                        // 记录不存在，新建记录
                        one = new ApiLog();
                        one.setApiName(apiName);
                        one.setCreateDate(LocalDate.now());
                        one.setDescFunction(description);
                        one.setModule(module);
                        one.setUserId(userId);
                        one.setChName(chName);
                        one.setTimes(1);
                    } else {
                        // 记录存在，则调用次数加一
                        one.setTimes(one.getTimes() + 1);
                    }
                    // 保存记录
                    apiLogService.saveOrUpdate(one);
                }
            }
        } catch (Exception e) {
            throw new ServiceException(Constants.CODE_401, "session过期");
        }

    }
}
